Skip to content

[fix](fe) Check all aggregate function arguments#65537

Open
morrySnow wants to merge 1 commit into
apache:masterfrom
morrySnow:fix-normalize-agg
Open

[fix](fe) Check all aggregate function arguments#65537
morrySnow wants to merge 1 commit into
apache:masterfrom
morrySnow:fix-normalize-agg

Conversation

@morrySnow

Copy link
Copy Markdown
Contributor

What problem does this PR solve?

Issue Number: None

Related PR: None

Problem Summary: NormalizeAggregate only checked the first child of each aggregate function for nested aggregate functions. Aggregate functions in later arguments, such as SUM in the ORDER BY argument of GROUP_CONCAT, could bypass analysis validation. Check every aggregate child and add FE unit and regression coverage for the invalid query.

Release note

Reject nested aggregate functions in every aggregate function argument.

Check List (For Author)

  • Test: Unit Test and Regression test
    • Unit Test: NormalizeAggregateTest
    • Regression test: query_p0/aggregate/agg_group_concat
  • Behavior changed: Yes, invalid nested aggregate functions in non-first arguments are rejected during analysis
  • Does this need documentation: No

@hello-stephen

Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

@morrySnow

Copy link
Copy Markdown
Contributor Author

/review

@morrySnow

Copy link
Copy Markdown
Contributor Author

run buildall

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found one correctness issue in the aggregate-parameter validation.

Critical checkpoints:

  • Goal: the PR intends to reject aggregate functions nested in aggregate parameters. It covers the simple non-distinct group_concat(k order by sum(k)) case, but the validation still runs after some aggregate-containing children can be normalized to slots.
  • Scope/focus: the code change is small, but the affected normalization path has parallel distinct and pushdown-triggered order-key branches.
  • Concurrency/lifecycle/config/persistence/FE-BE protocol: not involved.
  • Parallel paths: issue found in distinct non-slot children and non-distinct order keys containing pushdown-triggering expressions.
  • Tests: the new FE and regression tests use the right expected-error pattern, but they only cover the simple non-distinct order-key case and miss the variants in the inline comment.
  • User focus: no additional user-provided focus was supplied.

Validation was static only. I did not run builds or tests because this review prompt forbids builds/code modifications, and this checkout is not worktree-initialized and lacks thirdparty/installed / thirdparty/installed/bin/protoc.

bottomSlotContext.normalizeToUseSlotRef(SessionVarGuardExpr.getExprWithGuard(aggFuncs));
if (normalizedAggFuncs.stream().anyMatch(agg -> !agg.children().isEmpty()
&& agg.child(0).containsType(AggregateFunction.class))) {
&& agg.children().stream().anyMatch(e -> e.containsType(AggregateFunction.class)))) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check still runs too late for children that were put into needPushDownSelfExprs. For example, group_concat(distinct k order by sum(k)) unwraps the order key in the distinct branch and maps sum(k) to a bottom-project alias slot before this block runs; similarly, count(distinct sum(k)) or an order key like sum(k) + row_number() over(...) can be replaced by a slot first. After normalizeToUseSlotRef, the aggregate child no longer contains an AggregateFunction, so this check misses the nested aggregate and may only fail later as an aggregate pushed into the wrong plan node. Please validate the original aggregate children/order-key children for non-window aggregate functions before any slot normalization, and add coverage for the distinct and pushdown-triggered variants.

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29293 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit f5b93bea6ab86ca2f8d45523adea99e068f4ee19, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17605	4072	4018	4018
q2	2023	349	195	195
q3	10261	1405	815	815
q4	4684	464	336	336
q5	7634	845	569	569
q6	180	171	138	138
q7	778	831	618	618
q8	9327	1539	1487	1487
q9	5572	4364	4356	4356
q10	6765	1787	1537	1537
q11	496	363	308	308
q12	697	552	431	431
q13	18113	3355	2715	2715
q14	267	252	252	252
q15	q16	784	772	708	708
q17	983	974	1059	974
q18	7000	5601	5658	5601
q19	1328	1340	1045	1045
q20	797	635	547	547
q21	5992	2663	2344	2344
q22	432	356	299	299
Total cold run time: 101718 ms
Total hot run time: 29293 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4338	4283	4267	4267
q2	285	312	212	212
q3	4594	4937	4400	4400
q4	2030	2131	1386	1386
q5	4427	4350	4342	4342
q6	230	177	129	129
q7	1807	1596	2047	1596
q8	2657	2210	2184	2184
q9	8029	8166	7753	7753
q10	4722	4707	4268	4268
q11	556	420	376	376
q12	751	787	541	541
q13	3246	3640	2920	2920
q14	313	299	297	297
q15	q16	714	726	652	652
q17	1375	1325	1296	1296
q18	7959	7359	7364	7359
q19	1208	1116	1074	1074
q20	2205	2206	1923	1923
q21	5177	4534	4396	4396
q22	525	479	392	392
Total cold run time: 57148 ms
Total hot run time: 51763 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 180871 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit f5b93bea6ab86ca2f8d45523adea99e068f4ee19, data reload: false

query5	4339	631	492	492
query6	472	211	204	204
query7	4878	611	328	328
query8	334	183	177	177
query9	8799	4032	3994	3994
query10	474	352	296	296
query11	5886	2339	2129	2129
query12	167	106	103	103
query13	1277	694	436	436
query14	6270	5315	4981	4981
query14_1	4283	4301	4274	4274
query15	214	210	187	187
query16	1036	475	460	460
query17	1140	732	590	590
query18	2479	477	355	355
query19	206	197	154	154
query20	118	112	107	107
query21	236	158	135	135
query22	13660	13576	13438	13438
query23	17538	16462	16159	16159
query23_1	16303	16234	16212	16212
query24	7633	1775	1264	1264
query24_1	1318	1313	1299	1299
query25	571	474	390	390
query26	1342	364	209	209
query27	2568	623	378	378
query28	4426	2037	2002	2002
query29	1136	629	530	530
query30	347	261	230	230
query31	1115	1088	982	982
query32	118	66	64	64
query33	543	328	264	264
query34	1205	1138	639	639
query35	765	795	679	679
query36	1408	1419	1261	1261
query37	202	106	91	91
query38	1849	1685	1627	1627
query39	918	901	903	901
query39_1	873	911	903	903
query40	241	161	142	142
query41	66	66	62	62
query42	95	90	94	90
query43	317	314	273	273
query44	1396	773	765	765
query45	199	193	186	186
query46	1055	1179	699	699
query47	2410	2366	2232	2232
query48	411	407	293	293
query49	574	416	320	320
query50	1045	421	314	314
query51	10787	10893	10626	10626
query52	85	84	73	73
query53	250	278	192	192
query54	296	232	211	211
query55	74	72	64	64
query56	272	287	277	277
query57	1438	1423	1353	1353
query58	275	257	246	246
query59	1547	1651	1419	1419
query60	309	265	249	249
query61	148	148	147	147
query62	714	649	580	580
query63	240	202	202	202
query64	2791	1042	857	857
query65	4862	4794	5117	4794
query66	1814	529	411	411
query67	29558	29357	29782	29357
query68	3254	1584	960	960
query69	408	303	254	254
query70	1090	993	960	960
query71	344	319	325	319
query72	3058	2736	2389	2389
query73	828	745	441	441
query74	5111	4940	4761	4761
query75	2618	2584	2238	2238
query76	2356	1170	755	755
query77	363	370	283	283
query78	12350	12451	11748	11748
query79	1404	1204	783	783
query80	1291	527	451	451
query81	547	327	284	284
query82	810	157	121	121
query83	372	318	331	318
query84	282	159	127	127
query85	957	593	510	510
query86	433	287	283	283
query87	1825	1824	1760	1760
query88	3666	2758	2777	2758
query89	451	407	352	352
query90	1930	202	195	195
query91	199	189	158	158
query92	66	62	56	56
query93	1567	1560	1061	1061
query94	738	354	315	315
query95	774	477	555	477
query96	1012	810	325	325
query97	2694	2702	2521	2521
query98	209	212	200	200
query99	1150	1180	1027	1027
Total cold run time: 266245 ms
Total hot run time: 180871 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 25.04 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit f5b93bea6ab86ca2f8d45523adea99e068f4ee19, data reload: false

query1	0.01	0.01	0.00
query2	0.10	0.04	0.05
query3	0.26	0.15	0.14
query4	1.61	0.15	0.15
query5	0.26	0.23	0.22
query6	1.28	1.08	1.09
query7	0.04	0.00	0.01
query8	0.06	0.04	0.04
query9	0.38	0.30	0.31
query10	0.58	0.55	0.54
query11	0.20	0.14	0.14
query12	0.18	0.14	0.14
query13	0.47	0.48	0.47
query14	1.01	0.98	1.01
query15	0.61	0.59	0.59
query16	0.32	0.34	0.31
query17	1.10	1.08	1.14
query18	0.22	0.21	0.21
query19	2.01	1.96	1.97
query20	0.02	0.01	0.01
query21	15.44	0.21	0.13
query22	4.84	0.05	0.05
query23	16.23	0.32	0.11
query24	3.05	0.43	0.34
query25	0.11	0.05	0.04
query26	0.72	0.20	0.15
query27	0.04	0.03	0.04
query28	3.52	0.92	0.52
query29	12.50	4.15	3.29
query30	0.28	0.15	0.15
query31	2.78	0.58	0.31
query32	3.23	0.59	0.48
query33	3.15	3.22	3.25
query34	15.56	4.26	3.51
query35	3.48	3.52	3.50
query36	0.55	0.44	0.42
query37	0.09	0.07	0.06
query38	0.05	0.04	0.04
query39	0.04	0.03	0.03
query40	0.18	0.17	0.17
query41	0.08	0.04	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.03
Total cold run time: 96.72 s
Total hot run time: 25.04 s

@hello-stephen

Copy link
Copy Markdown
Contributor

FE UT Coverage Report

Increment line coverage 100.00% (1/1) 🎉
Increment coverage report
Complete coverage report

@hello-stephen

Copy link
Copy Markdown
Contributor

FE Regression Coverage Report

Increment line coverage 10.00% (1/10) 🎉
Increment coverage report
Complete coverage report

@morrySnow morrySnow force-pushed the fix-normalize-agg branch from f5b93be to 9804ea6 Compare July 14, 2026 09:55
@morrySnow

Copy link
Copy Markdown
Contributor Author

/review

@morrySnow

Copy link
Copy Markdown
Contributor Author

run buildall

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes for one correctness regression in NormalizeAggregate.

Critical checkpoint conclusions:

  • Goal: the PR aims to reject nested aggregate parameters earlier, but the current implementation also rejects valid top-level aggregates.
  • Scope: the patch is small and localized, but the validation scope is too broad.
  • Nereids rule behavior: CollectNonWindowedAggFuncsWithSessionVar collects aggregate roots, and the helper used by the new guard treats those roots as aggregate matches.
  • Tests: the added FE and regression tests cover the intended group_concat(k order by sum(k)) error shape, but I did not run tests because this review runner is static-only and lacks thirdparty/installed/protoc.
  • Existing review context: I did not duplicate the existing thread about validating original distinct/order-key children before slot normalization.
  • Concurrency, lifecycle, config, persistence, FE-BE protocol, cloud/shared-nothing, and observability: not involved in this patch.
  • User focus: no additional user-provided focus was present.

Round 2 convergence returned NO_NEW_VALUABLE_FINDINGS; the only accepted inline issue is below.

Issue Number: None

Related PR: None

Problem Summary: NormalizeAggregate only checked the first child of each aggregate function for nested aggregate functions. Aggregate functions in later arguments, such as SUM in the ORDER BY argument of GROUP_CONCAT, could bypass analysis validation. Check every aggregate child and add FE unit and regression coverage for the invalid query.

Reject nested aggregate functions in every aggregate function argument.

- Test: Unit Test and Regression test
    - Unit Test: NormalizeAggregateTest
    - Regression test: query_p0/aggregate/agg_group_concat
- Behavior changed: Yes, invalid nested aggregate functions in non-first arguments are rejected during analysis
- Does this need documentation: No
@morrySnow morrySnow force-pushed the fix-normalize-agg branch from 9804ea6 to a4ad850 Compare July 14, 2026 10:51
@morrySnow

Copy link
Copy Markdown
Contributor Author

run buildall

@morrySnow

Copy link
Copy Markdown
Contributor Author

/review

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the current PR head a4ad85013cd35b76ced1b7054c6a7475986c396d against the authoritative diff and existing review threads. I did not find a new non-duplicate issue to raise.

Checkpoint conclusions:

  • Goal: the patch moves nested aggregate validation before NormalizeAggregate slot normalization and now checks aggregate children/order keys before alias replacement.
  • Scope: the change is small and focused in NormalizeAggregate plus one FE unit test and one regression exception test.
  • Correctness: ordinary aggregates are not rejected because the aggregate root is no longer checked; nested non-window aggregates in arguments and group_concat ORDER BY keys are detected through the child scan; window aggregate order-key cases remain valid.
  • Parallel paths: distinct and group_concat ORDER BY paths use the same children/OrderExpression representation, and remaining explicit distinct/pushdown coverage concerns are already covered by existing thread discussion_r3569517204.
  • Tests: added FE unit and regression negative coverage for group_concat(k order by sum(k)); no result .out update is needed for the regression test { exception ... } block.
  • Concurrency/lifecycle/config/persistence/FE-BE protocol/data writes/observability: not materially involved by this FE analysis-rule change.
  • Performance: added traversal is limited to collected aggregate child expressions and is not a new hot-path concern.

No additional user-provided review focus was supplied.

Validation note: static review only. I did not run builds or tests because this review prompt forbids build attempts, and this checkout also lacks thirdparty/installed/bin/protoc.

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-H: Total hot run time: 29388 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpch-tools
Tpch sf100 test result on commit a4ad85013cd35b76ced1b7054c6a7475986c396d, data reload: false

------ Round 1 ----------------------------------
============================================
q1	17602	4045	4075	4045
q2	2019	319	220	220
q3	10316	1459	840	840
q4	4690	473	344	344
q5	7511	870	577	577
q6	190	174	140	140
q7	783	835	612	612
q8	9403	1581	1582	1581
q9	5493	4344	4310	4310
q10	6765	1745	1485	1485
q11	499	338	315	315
q12	698	544	421	421
q13	18141	3421	2742	2742
q14	270	270	245	245
q15	q16	787	772	710	710
q17	1021	950	867	867
q18	7166	5965	5640	5640
q19	1310	1233	1059	1059
q20	759	679	587	587
q21	5904	2588	2346	2346
q22	443	354	302	302
Total cold run time: 101770 ms
Total hot run time: 29388 ms

----- Round 2, with runtime_filter_mode=off -----
============================================
q1	4388	4293	4344	4293
q2	291	315	208	208
q3	4587	4986	4388	4388
q4	2039	2164	1363	1363
q5	4390	4303	4273	4273
q6	227	175	128	128
q7	1737	1727	1801	1727
q8	2651	2241	2193	2193
q9	8066	8111	7892	7892
q10	4707	4652	4246	4246
q11	568	411	389	389
q12	778	788	561	561
q13	3274	3640	2990	2990
q14	308	320	274	274
q15	q16	726	730	639	639
q17	1309	1312	1430	1312
q18	7764	7301	7297	7297
q19	1179	1054	1088	1054
q20	2204	2218	1938	1938
q21	5234	4560	4383	4383
q22	516	473	416	416
Total cold run time: 56943 ms
Total hot run time: 51964 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
TPC-DS: Total hot run time: 177594 ms
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/tpcds-tools
TPC-DS sf100 test result on commit a4ad85013cd35b76ced1b7054c6a7475986c396d, data reload: false

query5	4328	617	488	488
query6	466	223	208	208
query7	4844	578	354	354
query8	333	185	175	175
query9	8733	4009	4039	4009
query10	462	334	302	302
query11	5916	2347	2152	2152
query12	157	103	102	102
query13	1266	583	429	429
query14	6243	5233	4891	4891
query14_1	4232	4248	4248	4248
query15	229	211	180	180
query16	1030	465	441	441
query17	1143	738	584	584
query18	2541	478	356	356
query19	226	197	154	154
query20	119	110	106	106
query21	232	164	135	135
query22	13606	13583	13419	13419
query23	17338	16505	16101	16101
query23_1	16256	16100	16165	16100
query24	7481	1753	1308	1308
query24_1	1321	1282	1282	1282
query25	566	470	389	389
query26	1336	367	213	213
query27	2582	578	385	385
query28	4405	1972	1976	1972
query29	1085	649	466	466
query30	337	263	224	224
query31	1112	1087	975	975
query32	106	60	60	60
query33	504	305	243	243
query34	1164	1135	611	611
query35	755	774	655	655
query36	1207	1161	1099	1099
query37	154	109	89	89
query38	1859	1679	1657	1657
query39	869	894	837	837
query39_1	816	818	839	818
query40	250	163	135	135
query41	65	65	62	62
query42	92	95	90	90
query43	314	318	282	282
query44	1407	780	769	769
query45	198	181	169	169
query46	1049	1211	705	705
query47	2130	2114	2001	2001
query48	395	410	301	301
query49	578	421	304	304
query50	994	417	323	323
query51	10523	10824	10468	10468
query52	87	86	73	73
query53	263	285	205	205
query54	294	228	241	228
query55	74	75	65	65
query56	298	290	273	273
query57	1331	1283	1198	1198
query58	276	258	259	258
query59	1567	1596	1494	1494
query60	297	261	272	261
query61	158	148	157	148
query62	547	509	431	431
query63	240	206	196	196
query64	2770	1056	865	865
query65	4732	4628	4590	4590
query66	1765	513	368	368
query67	28799	29196	29201	29196
query68	3129	1552	1008	1008
query69	410	315	267	267
query70	1086	945	909	909
query71	356	317	306	306
query72	3126	2682	2378	2378
query73	825	727	430	430
query74	5065	4940	4698	4698
query75	2503	2496	2109	2109
query76	2304	1188	785	785
query77	351	374	279	279
query78	11808	11909	11279	11279
query79	1370	1113	749	749
query80	1302	536	445	445
query81	521	317	272	272
query82	768	157	125	125
query83	392	322	291	291
query84	276	160	129	129
query85	970	592	508	508
query86	423	297	290	290
query87	1827	1823	1743	1743
query88	3683	2776	2750	2750
query89	427	364	333	333
query90	1939	200	195	195
query91	196	188	161	161
query92	61	64	58	58
query93	1611	1616	972	972
query94	726	365	319	319
query95	775	569	481	481
query96	1070	774	337	337
query97	2624	2623	2499	2499
query98	210	211	200	200
query99	1082	1113	973	973
Total cold run time: 262430 ms
Total hot run time: 177594 ms

@hello-stephen

Copy link
Copy Markdown
Contributor
ClickBench: Total hot run time: 24.97 s
machine: 'aliyun_ecs.c7a.8xlarge_32C64G'
scripts: https://github.com/apache/doris/tree/master/tools/clickbench-tools
ClickBench test result on commit a4ad85013cd35b76ced1b7054c6a7475986c396d, data reload: false

query1	0.00	0.01	0.00
query2	0.10	0.05	0.05
query3	0.26	0.14	0.14
query4	1.63	0.14	0.14
query5	0.24	0.22	0.22
query6	1.27	1.08	1.02
query7	0.05	0.01	0.01
query8	0.07	0.04	0.04
query9	0.38	0.31	0.31
query10	0.55	0.56	0.54
query11	0.20	0.14	0.14
query12	0.18	0.14	0.14
query13	0.48	0.47	0.46
query14	1.01	1.00	0.99
query15	0.61	0.58	0.60
query16	0.32	0.33	0.34
query17	1.12	1.16	1.09
query18	0.22	0.20	0.20
query19	2.04	2.01	2.00
query20	0.02	0.01	0.01
query21	15.44	0.23	0.14
query22	4.93	0.06	0.05
query23	16.13	0.31	0.12
query24	3.03	0.44	0.32
query25	0.11	0.05	0.05
query26	0.72	0.20	0.16
query27	0.04	0.04	0.04
query28	3.54	0.92	0.55
query29	12.47	4.04	3.20
query30	0.27	0.16	0.15
query31	2.76	0.62	0.31
query32	3.22	0.60	0.49
query33	3.20	3.27	3.15
query34	15.47	4.24	3.50
query35	3.53	3.53	3.58
query36	0.56	0.44	0.42
query37	0.09	0.07	0.07
query38	0.05	0.04	0.03
query39	0.04	0.03	0.03
query40	0.18	0.16	0.15
query41	0.08	0.03	0.03
query42	0.04	0.03	0.03
query43	0.04	0.04	0.04
Total cold run time: 96.69 s
Total hot run time: 24.97 s

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants